package com.ruoyi.personnel.oa.uploadAndDownload.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.personnel.oa.uploadAndDownload.config.FilesConfig;
import com.ruoyi.personnel.oa.uploadAndDownload.service.UploadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.unit.DataSize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

@RestController
@RequestMapping("/oa/file")
@Api(value = "文件上传", tags = "文件上传接口")
public class UploadController extends BaseController {
    @Autowired
    private FilesConfig filesConfig;
    @Autowired
    private UploadService fileService;

//    @ApiOperation("单文件上传")
//    @RequestMapping("/upload")

    /**
     * 设置文件上传大小：在配置文件中限定
     *
     * @return
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //单个文件最大
        factory.setMaxFileSize(DataSize.parse(filesConfig.getMaxFileSize()));
        //设置总上传数据总大小
        factory.setMaxRequestSize(DataSize.parse(filesConfig.getMaxRequestSize()));
        return factory.createMultipartConfig();
    }

    /**
     * 单文件上传
     *
     * @param file
     * @return
     * @throws IOException
     */
    @ApiOperation("单文件上传")
    @PostMapping("/uploadOne")
    public AjaxResult uploadOne(MultipartFile file) throws IOException {
        String uploadOne = UploadService.uploadOne(file, filesConfig.getTemporaryPath());
        return AjaxResult.success("上传成功", uploadOne);
    }

//    /**
//     * 多文件上传
//     *
//     * @param files
//     * @return
//     * @throws IOException
//     */
//    @PostMapping("/uploadMore")
//    public AjaxResult uploadMore(MultipartFile[] files) throws IOException {
//        String uploadMore = UploadService.uploadMore(files, filesConfig.getTemporaryPath());
//        String[] uploadMores = uploadMore.split(",");
//        return AjaxResult.success("上传成功", uploadMores);
//    }

    //    /**
//     * 文件转移：适用于多文件以及单文件
//     *
//     * @param uploadPath
//     * @return
//     * @throws IOException
//     */
//    @PostMapping("/change")
//    public JsonResult filesChange(@RequestBody String[] uploadPath) throws IOException {
//        //循环遍历传来的String数组
//        for (String u : uploadPath) {
//            //拿到临时目录的文件
//            String path = filesConfig.getTemporaryPath() + u;
//            File file = new File(path);
//            //File类型转换为MultipartFile类型
//            MultipartFile multipartFile = new MockMultipartFile(file.getName(), new FileInputStream(file));
//            //正式目录名与文件名生成一个新的路径
//            String newPath = filesConfig.getFormalPath() + u;
//            File newFile = new File(newPath);
//            //判断文件目录是否存在
//            if (!newFile.getParentFile().exists()) {
//                //创建文件存放目录
//                //无论是几个/，都是创建一个文件夹
//                //mkdirs(): 创建多层目录，如：E:/upload/2019
//                //mkdir(): 只创建一层目录，如：E:upload
//                //如果不加这一行不会创建新的文件夹，会报系统找不到路径
//                newFile.getParentFile().mkdirs();
//            }
//            //存储文件
//            multipartFile.transferTo(newFile);
//            //去掉目录名，保留文件总体路径，通过该路径访问图片
//        }
//        return ResponseResult.Success(ResultCodeEnums.SUCCESS);
//    }

//    /**
//     * 文件下载
//     *
//     * @param name
//     * @param response
//     * @throws Exception
//     */
//    @ApiOperation("文件下载")
//    @GetMapping(value = "/download/{name}")
//    public void logDownload(@PathVariable String name, HttpServletResponse response) throws Exception {
////        fileService.logDownload(name, response);
//        try {
//            String filePath = "D:/ruoyi/uploadPath/flies" + File.separator + name;
//
//            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
//            FileUtils.setAttachmentResponseHeader(response, name);
//            FileUtils.writeBytes(filePath, response.getOutputStream());
//        } catch (
//                Exception e) {
////            log.error("下载文件失败", e);
//        }
//    }

    /**
     * 文件下载
     * @param fileId
     * @param request
     * @return
     * @throws Exception
     */
    @ApiOperation("文件下载")
    @GetMapping(value = "/download/fileId/{fileId}")
    public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable("fileId") String fileId, HttpServletRequest request) throws Exception {
        // 这里根据我给定的fileId来下载指定的文件，
        // 如果你想根据其他方式来下载指定文件的话，请自己修改业务逻辑
        // 1. 根据fileId从数据库中获取到指定的文件信息，包括文件名、文件存储地址等等。
        // 1.1 假设我已经获取到了文件信息。
        String fileName = new String("aaa.docx".getBytes(StandardCharsets.UTF_8), "iso-8859-1");
        String filePath = "D:/ruoyi/uploadPath/flies/aaa.docx";

        // 2. 解决下载的文件的文件名出现中文乱码
        String userAgent = request.getHeader("User-Agent");
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            // IE浏览器
            fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
        } else {
            // 非IE浏览器
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }

        // 3. 下载文件
        byte[] data = Files.readAllBytes(Paths.get(filePath));
        ByteArrayResource resource = new ByteArrayResource(data);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "iso-8859-1"))
                .contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(data.length)
                .body(resource);
    }
}
